package com.asdhawaii.otello.players;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.asdhawaii.otello.board.Direction;
import com.asdhawaii.otello.board.Move;
import com.asdhawaii.otello.board.Square;
import com.asdhawaii.otello.board.SquareContents;

/**
 * A low-level Otello AI that selects the move that will flip the greatest number of pieces.
 * 
 * @author Branden Ogata
 *
 */

public class Level1Ai extends AbstractOtelloAi
{
  /**
   * Creates a new Level1Ai.
   * 
   * @param color The SquareContents indicating the color of the pieces for the new LevelAi.
   * 
   */
  
  public Level1Ai(SquareContents color)
  {
    super(color);
  }

  /**
   * Returns the move or one of the moves that would flip the most pieces.
   * 
   * @param board The Square[][] representing the Otello board.
   * @param moves The List<Move> containing the valid moves on the board.
   * 
   * @return A Move representing the selected move.
   * 
   */
  
  @Override
  public Move getMove(Square[][] board, List<Move> moves)
  {
    // Testing: prints out the board
    for (int i = 0; i < board.length; i++)
    {
      for (int j = 0; j < board[i].length; j++)
      {
        System.out.print(board[i][j]);
      }
      
      System.out.println();
    }
    
    List<Move> candidates = new ArrayList<Move>();
    int mostFlips = 0;
    
    // For each legal move
    for (Move move : moves)
    {
      int currentFlips = 0;
      
      // Find the number of flipped pieces in all directions
      for (Direction d : Direction.values())
      {
        currentFlips += this.getFlips(board, move.getColumn() + d.getDeltaX(), 
                                      move.getRow() + d.getDeltaY(), d);
      }

      System.out.format("%s: %d flips%n", move, currentFlips);
      
      // If the number of current flips is greater than the previous most flips,
      // then update the selection
      if (currentFlips > mostFlips)
      {
        mostFlips = currentFlips;
        candidates.clear();
        candidates.add(move);
      }
      // If the number of current flips is equal to the previous most flips,
      // then add to the selection candidates
      else if (currentFlips == mostFlips)
      {
        candidates.add(move);
      }
    }
    
    System.out.println();
    
    Random random = new Random();
    Move selection = (candidates.isEmpty()) ? (null) : 
                                              (candidates.get(random.nextInt(candidates.size())));
    System.out.println("Selected " + selection);
    return selection;
  }
  
  /**
   * Returns the number of flipped pieces on the given board going in the given Direction.
   * 
   * @param board The Square[][] representing the Otello board.
   * @param x The int equal to the x coordinate of the Square to examine.
   * @param y The int equal to the y coordinate of the Square to examine.
   * @param direction The Direction equal to the direction in which to travel.
   * 
   * @return An int equal to the number of flipped enemy pieces resulting from the move.
   * 
   */
  
  public int getFlips(Square[][] board, int x, int y, Direction direction)
  {
    int flips = 0;
    
    if (this.isValidMove(board, x, y, direction, this.getColor().toString()))
    {
      flips = 1 + getFlips(board, x + direction.getDeltaX(), y + direction.getDeltaY(), direction);
    }
    
    return flips;
  }
}